///////////////////////////////////////////////////////////////////////////////
//
// Licensed under the MIT License
//
// Copyright (c) 2010 Chris Colinsky
// All Rights Reserved
//
// version	0.5
// http://code.google.com/p/sugarcookie/
// http://code.google.com/p/sugarcookie/wiki/License
//
////////////////////////////////////////////////////////////////////////////////

package sugarcookie.data.handlers.remoting {
	import com.dannypatterson.remoting.FaultEvent;
	import com.dannypatterson.remoting.ResultEvent;
	import com.dannypatterson.remoting.ServiceProxy;
	
	import flash.events.EventDispatcher;
	
	import mx.logging.ILogger;
	import mx.utils.ObjectUtil;
	
	import sugarcookie.error.ApplicationError;
	import sugarcookie.events.DataEvent;
	import sugarcookie.events.GenericEvent;
	import sugarcookie.data.handlers.IDataHandler;
	
	/**
	 * Creates a data channel that works with Danny Patterson's Remoting classes.
	 */
	public class RemotingHandler extends EventDispatcher implements IDataHandler {
		private var _isAutoLoad:Boolean = false;
		private var _id:String = "REMOTING";
		private var _service:String;
		protected var _serviceProxy:ServiceProxy;
		protected var _log:ILogger;
		
		public function RemotingHandler(gateway:String, service:String, useOperationPooling:Boolean = true) {
			super(this);
			_service = service;
			_serviceProxy = new ServiceProxy(gateway, service, useOperationPooling);
			_serviceProxy.addEventListener(ResultEvent.RESULT, onResult, false, 0, true);
			_serviceProxy.addEventListener(FaultEvent.FAULT, onFault, false, 0, true);
			_serviceProxy.addEventListener(FaultEvent.CONNECTION_ERROR, onConnectionError, false, 0, true);
		}
		
		public function call(methodName:String, arguments:Array):void {
			_log.info("call: " + methodName);
			_serviceProxy.call(methodName, arguments);
		}
		
		public function get autoLoad():Boolean { return _isAutoLoad; }
		public function set autoLoad(value:Boolean):void { _isAutoLoad = value; }
		
		public function get id():String { return _id; }
		public function set id(value:String):void { _id = value; }
		
		public function kill():void {
			_serviceProxy = null;
		}
		
		public function init():void {
		}
		
		private function onConnectionError(evt:FaultEvent):void {
			_log.debug("onConnectionError: " + evt.fault);
			dispatchEvent(new GenericEvent(DataEvent.ON_DATA_CHANNEL_ERROR,false,false,"REMOTING-"+_service.toUpperCase(),true,{error:evt.fault}));
			throw new ApplicationError(evt.fault.toString());
		}
		
		protected function onFault(evt:FaultEvent):void {
			_log.debug("onFault: " + evt.fault.toString());
			dispatchEvent(new GenericEvent(DataEvent.ON_DATA_CHANNEL_ERROR,false,false,"REMOTING-"+_service.toUpperCase(),true,{error:evt.fault}));
		}
		
		protected function onResult(evt:ResultEvent):void {
			_log.debug("onResult: " + ObjectUtil.toString(evt.result));
			dispatchEvent(new GenericEvent(DataEvent.ON_DATA_CHANNEL_RETURN,false,false,"REMOTING-"+_service.toUpperCase(),true,{result:evt.result}));
		}
	}
}